package com.tobby.camel.camelinaction.chapter3.order;

import java.io.InputStream;
import java.io.OutputStream;
import java.text.Normalizer.Form;

import org.apache.camel.Exchange;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.spi.DataFormat;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Test;
import org.springframework.test.context.TestExecutionListeners;

public class ReverseDataformatTest extends CamelTestSupport {

	@Override
	public RouteBuilder createRouteBuilder() {
		return new RouteBuilder() {
			
			@Override
			public void configure() throws Exception {
				from("direct:reverseString").marshal(new ReverseDataFormat()).to("log:marshal");
				from("direct:unmarshal").unmarshal(new ReverseDataFormat()).log("log:unmarshal");
			}
		};
	}

	@Test
	public void testReverseString() {
		String marshalOut = template.requestBody("direct:reverseString", "I Love You", String.class);
		assertEquals("uoY evoL I", marshalOut);
		String unmarshalOut = template.requestBody("direct:unmarshal", "uoY evoL I", String.class);
		assertEquals("I Love You", unmarshalOut);
	}

	public static class ReverseDataFormat implements DataFormat {

		@Override
		public void marshal(Exchange exchange, Object graph, OutputStream stream)
				throws Exception {
			byte[] bytes = exchange.getContext().getTypeConverter()
					.mandatoryConvertTo(byte[].class, graph);
			String body = reverseBytes(bytes);
			stream.write(body.getBytes());
		}

		@Override
		public Object unmarshal(Exchange exchange, InputStream stream) throws Exception {
			byte[] bytes = exchange.getContext().getTypeConverter()
					.mandatoryConvertTo(byte[].class, stream);
			String body = reverseBytes(bytes);
			return body;
		}

		private static String reverseBytes(byte[] data) {
			StringBuilder sb = new StringBuilder(data.length);
			for (int i = data.length - 1; i >= 0; i--) {
				char ch = (char) data[i];
				sb.append(ch);
			}
			return sb.toString();
		}

	}

}
